package com.xujicheng.dingtalk.service;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.xujicheng.dingtalk.oauth2.DingtalkOAuth2AccessToken;
import com.xujicheng.dingtalk.properties.DingtalkProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * 钉钉部门api
 * @author: xujicheng
 * @project dingtalk-utils
 * @packge com.xujicheng.dingtalk.service
 * @date: 2018/7/11 16:16
 * @description:
 */
@Component
public class DingTalkDepartmentService {

    @Autowired
    private DingtalkOAuth2AccessToken dingtalkOAuth2AccessToken;
    @Autowired
    private DingtalkProperties dingtalkProperties;

    /**
     * 查询部门列表
     * @param parentId 父部门ID 如果不传入则默认是1
     * @param fetchChild 是否递归部门全部子部门 默认是false
     * @return
     * {
     *     "errcode": 0,
     *     "errmsg": "ok",
     *     "department": [  //部门列表数据，以部门的order字段从小到大排列
     *         {
     *            "id": 2, //部门id
     *             "name": "钉钉事业部", //部门名称
     *             "parentid": 1, //父部门id，根部门为1
     *             "createDeptGroup": true, //是否同步创建一个关联此部门的企业群,true表示是,false表示不是
     *             "autoAddUser": true //当群已经创建后，是否有新人加入部门会自动加入该群,true表示是,false表示不是
     *         },
     *         {
     *             "id": 3,
     *             "name": "服务端开发组",
     *             "parentid": 2,
     *             "createDeptGroup": false,
     *             "autoAddUser": false
     *         }
     *     ]
     * }
     * @throws ApiException
     */
    public OapiDepartmentListResponse getDepartmentList(String parentId, Boolean fetchChild) throws ApiException {
        if(null == parentId){
            parentId = "1";
        }
        if(null == fetchChild){
            fetchChild = false;
        }
        DingTalkClient client = new DefaultDingTalkClient(dingtalkProperties.getApi().getDepartment_list());
        OapiDepartmentListRequest request = new OapiDepartmentListRequest();
        request.setId(parentId);
        request.setHttpMethod("GET");
        request.setFetchChild(fetchChild);
        return client.execute(request, dingtalkOAuth2AccessToken.getAccessToken());
    }

    /**
     * 获取部门详情
     * @param id
     * @return {
     *     "errcode": 0,  //返回码
     *     "errmsg": "ok", //对返回码的文本描述内容
     *     "id": 2, //部门id
     *     "name": "钉钉事业部", //部门名称
     *     "order" : 10, //在父部门中的次序值
     *     "parentid": 1, //父部门id，根部门为1
     *     "createDeptGroup": true, //是否同步创建一个关联此部门的企业群,true表示是,false表示不是
     *     "autoAddUser": true, //当群已经创建后，是否有新人加入部门会自动加入该群,true表示是,false表示不是
     *     "deptHiding" : true, //是否隐藏部门,true表示隐藏，false表示显示
     *     "deptPerimits" : "3|4", //可以查看指定隐藏部门的其他部门列表，如果部门隐藏，则此值生效，取值为其他的部门id组成的的字符串，使用“|”符号进行分割
     *     "userPerimits" : "userid1|userid2", //可以查看指定隐藏部门的其他人员列表，如果部门隐藏，则此值生效，取值为其他的人员userid组成的的字符串，使用“|”符号进行分割
     *     "outerDept" : true, //是否本部门的员工仅可见员工自己，为true时，本部门员工默认只能看到员工自己
     *     "outerPermitDepts" : "1|2", //本部门的员工仅可见员工自己为true时，可以配置额外可见部门，值为部门id组成的的字符串，使用“|”符号进行分割
     *     "outerPermitUsers" : "userid3|userid4", //本部门的员工仅可见员工自己为true时，可以配置额外可见人员，值为userid组成的的字符串，使用“|”符号进行分割
     *     "orgDeptOwner" : "manager1122", //企业群群主
     *     "deptManagerUseridList" : "manager1122|manager3211", //部门的主管列表，取值为由主管的userid组成的字符串，不同的userid使用“|”符号进行分割
     *     "sourceIdentifier" : "source" //部门标识字段，开发者可用该字段来唯一标识一个部门，并与钉钉外部通讯录里的部门做映射
     *     "groupContainSubDept" : false //部门群是否包含子部门
     *  }
     * @throws ApiException
     */
    public OapiDepartmentGetResponse getDepartment(String id) throws ApiException {
        Assert.isTrue(StringUtils.hasLength(id),"部门ID未设定");
        DingTalkClient client = new DefaultDingTalkClient(dingtalkProperties.getApi().getDepartment_get());
        OapiDepartmentGetRequest request = new OapiDepartmentGetRequest();
        request.setId(id);
        request.setHttpMethod("GET");
        OapiDepartmentGetResponse response = client.execute(request, dingtalkOAuth2AccessToken.getAccessToken());
        return response;
    }

    /**
     * 新建部门
     * @param request 入参对象
     * @param request#{name} 必须 部门名称，长度限制为1~64个字符，不允许包含字符‘-’‘，’以及‘,’
     * @param request#{parentid} 必须 父部门id，根部门id为1 默认是1
     * @param request#{order} 在父部门中的次序值，order值小的排序靠前
     * @param request#{createDeptGroup} 是否创建一个关联此部门的企业群，默认为false
     * @param request#{deptHiding} 是否隐藏部门,true表示隐藏 false表示显示
     * @param request#{deptPerimits} 可以查看指定隐藏部门的其他部门列表，如果部门隐藏，则此值生效，取值为其他的部门id组成的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{userPerimits} 可以查看指定隐藏部门的其他人员列表，如果部门隐藏，则此值生效，取值为其他的人员userid组成的的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{outerDept} 是否本部门的员工仅可见员工自己，为true时，本部门员工默认只能看到员工自己
     * @param request#{outerPermitDepts} 本部门的员工仅可见员工自己为true时，可以配置额外可见部门，值为部门id组成的的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{outerPermitUsers} 本部门的员工仅可见员工自己为true时，可以配置额外可见人员，值为userid组成的的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{sourceIdentifier} 部门标识字段，开发者可用该字段来唯一标识一个部门，并与钉钉外部通讯录里的部门做映射
     * @return {"errcode": 0,"errmsg": "created","id": 2}
     * @throws ApiException
     */
    public OapiDepartmentCreateResponse createDepartment(OapiDepartmentCreateRequest request) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(dingtalkProperties.getApi().getDepartment_create());
        if(StringUtils.isEmpty(request.getParentid())){
            request.setParentid("1");
        }
        return client.execute(request, dingtalkOAuth2AccessToken.getAccessToken());
    }

    /**
     *
     * @param request
     * @param request#{name} 必须 部门名称，长度限制为1~64个字符，不允许包含字符‘-’‘，’以及‘,’
     * @param request#{parentid} 必须 父部门id，根部门id为1 默认是1
     * @param request#{order} 在父部门中的次序值，order值小的排序靠前
     * @param request#{id} 部门id
     * @param request#{createDeptGroup} 是否创建一个关联此部门的企业群，默认为false
     * @param request#{autoAddUser} 如果有新人加入部门是否会自动加入部门群
     * @param request#{orgDeptOwner} 企业群群主
     * @param request#{deptManagerUseridList} 部门的主管列表,取值为由主管的userid组成的字符串，不同的userid使用“|”符号进行分割
     * @param request#{deptHiding} 是否隐藏部门,true表示隐藏 false表示显示
     * @param request#{deptPerimits} 可以查看指定隐藏部门的其他部门列表，如果部门隐藏，则此值生效，取值为其他的部门id组成的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{userPerimits} 可以查看指定隐藏部门的其他人员列表，如果部门隐藏，则此值生效，取值为其他的人员userid组成的的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{outerDept} 是否本部门的员工仅可见员工自己，为true时，本部门员工默认只能看到员工自己
     * @param request#{outerPermitDepts} 本部门的员工仅可见员工自己为true时，可以配置额外可见部门，值为部门id组成的的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{outerPermitUsers} 本部门的员工仅可见员工自己为true时，可以配置额外可见人员，值为userid组成的的字符串，使用“|”符号进行分割。总数不能超过200
     * @param request#{sourceIdentifier} 部门标识字段，开发者可用该字段来唯一标识一个部门，并与钉钉外部通讯录里的部门做映射
     * @return {"errcode": 0,"errmsg": "ok","id": 61602002}
     * @throws ApiException
     */
    public OapiDepartmentUpdateResponse updateDepartment(OapiDepartmentUpdateRequest request) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(dingtalkProperties.getApi().getDepartment_update());
        return client.execute(request, dingtalkOAuth2AccessToken.getAccessToken());
    }


    /**
     * 删除部门
     * @param id 部门id
     * @return {"errcode": 0,"errmsg": "ok"}
     * @throws ApiException
     */
    public OapiDepartmentDeleteResponse deleteDepartment(String id) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(dingtalkProperties.getApi().getDepartment_delete());
        OapiDepartmentDeleteRequest request = new OapiDepartmentDeleteRequest();
        request.setId(id);
        request.setHttpMethod("GET");
        return client.execute(request, dingtalkOAuth2AccessToken.getAccessToken());
    }
}
